<template>
  <div class="side-av-window-module" @mouseenter.stop.prevent="showControls"
       @mouseleave.stop.prevent="hideControlsAfterDelay">
    <span style="color: #fffff1 ; font-size: 12px ; line-height: 12px; margin-left: 5px; position: absolute">{{ remoteCallUser.nickname }}</span>
    <video ref="remoteStream" autoplay/>
    <div class="video-controls" :class="{ 'controls-visible': showControlsFlag }">
      <!-- 音频开关按钮 -->
<!--      <div-->
<!--          class="control-btn"-->
<!--          :style="{ backgroundColor: 'rgba(34, 34, 34, 0.3)'}"-->
<!--      >-->
<!--        <font-awesome-icon-->
<!--            :icon="['fas', 'microphone']"-->
<!--            :style="{ color: '#222' }"-->
<!--        />-->
<!--      </div>-->
<!--      &lt;!&ndash; 视频开关按钮 &ndash;&gt;-->
<!--      <div-->
<!--          class="control-btn"-->
<!--          :style="{ backgroundColor: 'rgba(34, 34, 34, 0.3)' }"-->
<!--      >-->
<!--        <font-awesome-icon-->
<!--            :icon="['fas', 'video']"-->
<!--            :style="{ color: '#222' }"-->
<!--        />-->
<!--      </div>-->
      <!-- 录制开关按钮 -->
<!--      <div-->
<!--          class="control-btn"-->
<!--          :style="{ backgroundColor:'rgba(34, 34, 34, 0.3)' }"-->
<!--      >-->
<!--        <font-awesome-icon-->
<!--            :icon="['fas', 'record-vinyl']"-->
<!--            :style="{ color: '#222' }"-->
<!--        />-->
<!--      </div>-->

      <div
          class="control-btn"
          :style="{ backgroundColor:'rgba(255, 0, 0, 0.3)' }"
          @click="hangup"
      >
        <font-awesome-icon
            :icon="['fas', 'phone-slash']"
            :style="{ color: 'red' }"
        />
      </div>
      <div class="control-btn" v-if="!castFullScreen"  :style="{ backgroundColor: 'rgba(255, 0, 0, 0.3)' }" @click="swapWindow">
        <font-awesome-icon :icon="['fas', 'up-right-and-down-left-from-center']"  :style="{ color: 'red' }"/>
      </div>
      <div class="control-btn" v-if="castFullScreen" :style="{ backgroundColor: 'rgba(255, 0, 0, 0.3)' }" @click="swapWindow">
        <font-awesome-icon :icon="['fas', 'down-left-and-up-right-to-center']"  :style="{ color: 'red' }"/>
      </div>
    </div>
  </div>
</template>

<script>
import {
  reportWebRtcAnswer,
  reportWebRtcCandidate,
  reportWebRtcHangup,
  reportWebRtcOffer,
  subWebRtcAnswer,
  subWebRtcCandidate,
  subWebRtcHangup,
  subWebRtcOffer,
  unSubWebRtcAnswer,
  unSubWebRtcCandidate,
  unSubWebRtcHangup,
  unSubWebRtcOffer
} from "@/api/nats/private_chat";

export default {
  name: 'RemoteWindow',
  inject: ['localStream' , 'callCommand'],
  props: {
    exitSingleChat: Function,
    singleCallSession: Object,
    swapSingleChatWindow: Function,
  },
  data() {
    return {
      castFullScreen: false,
      showControlsFlag: false,
      hideTimer: null,
      callId: null,
      remoteCallUser: null,
      localCallUser: null,
      currentStream: null,

      pc: new RTCPeerConnection({
        iceServers: [
          {urls: 'stun:stun.l.google.com:19302'},
          {urls: 'stun:stun1.l.google.com:19302'},
          {urls: 'stun:stun2.l.google.com:19302'}
        ]
      })
    }
  },
  methods: {
    // 显示控件组
    showControls() {
      clearTimeout(this.hideTimer);
      this.showControlsFlag = true;
    },
    // 2s 后隐藏控件组
    hideControlsAfterDelay() {
      this.hideTimer = setTimeout(() => {
        this.showControlsFlag = false;
      }, 1000);
    },
    setPCMediaTrack() {
      let stream = this.localStream.using === 'camera' ? this.localStream.cameraStream : this.localStream.screenStream;
      stream.getTracks().forEach(track => {
        this.pc.addTrack(track, stream);
      })
    },
    resetPCMediaTrack() {
      this.pc.getSenders().forEach(sender => {
        if (sender.track) {
          this.pc.removeTrack(sender);   // 标记为“不再发送”
        }
      });
      this.setPCMediaTrack();
      this.sendOffer(true, true);
    },
    init() {
      const {call, isCaller} = this.singleCallSession;
      this.callId = call.callId;
      if (isCaller) {
        this.remoteCallUser = call.callee;
        this.localCallUser = call.caller;
      } else {
        this.remoteCallUser = call.caller;
        this.localCallUser = call.callee;
      }

      subWebRtcOffer(this.localCallUser.id, this.callId, this.onOffer);
      subWebRtcAnswer(this.localCallUser.id, this.callId, this.onAnswer);
      subWebRtcCandidate(this.localCallUser.id, this.callId, this.onCandidate);
      subWebRtcHangup(this.localCallUser.id, this.callId, this.receivedHangup);

      this.setPCMediaTrack();

      this.onRTCPeerConnectionEvent();
      if (isCaller) {
        this.sendOffer();
      }
    },
    async sendOffer(offerToReceiveAudio = true, offerToReceiveVideo = true) {
      const offer = await this.pc.createOffer({
        offerToReceiveAudio,
        offerToReceiveVideo
      });
      await this.pc.setLocalDescription(offer);
      reportWebRtcOffer(this.remoteCallUser.id, this.callId, {
        callId: this.callId,
        type: "offer",
        remoteCallUser: this.localCallUser,
        offer
      })
    },
    async onOffer(webrtcOffer) {
      const {remoteCallUser, offer} = webrtcOffer
      console.log(`接收到来自${remoteCallUser.nickname}offer`)
      await this.pc.setRemoteDescription(new RTCSessionDescription(offer))

      const answer = await this.pc.createAnswer();
      await this.pc.setLocalDescription(answer);
      console.log(`发送answer 给${remoteCallUser.nickname}`)
      reportWebRtcAnswer(this.remoteCallUser.id, this.callId, {
        callId: this.callId,
        type: "answer",
        remoteCallUser: this.localCallUser,
        answer: this.pc.localDescription
      })
    },
    async onAnswer(webrtcAnswer) {
      const {remoteCallUser, answer} = webrtcAnswer
      console.log(`接收到来自${remoteCallUser.nickname}answer`)
      await this.pc.setRemoteDescription(new RTCSessionDescription(answer))
    },
    hangup() {
      this.exitSingleChat();
    },
    receivedHangup() {
      this.$message.warning(`${this.remoteCallUser.nickname}挂断通话`)
      this.exitSingleChat();
    },
    onErrorHangup() {
      this.$message.warning(`${this.remoteCallUser.nickname}异常断开`)
      this.exitSingleChat();
    },
    onCandidate(webrtcCandidate) {
      const {remoteCallUser, candidate} = webrtcCandidate
      console.log(`接收到来自${remoteCallUser.nickname}的candidate`, candidate)
      this.pc.addIceCandidate(new RTCIceCandidate(candidate))
    },
    onRTCPeerConnectionEvent() {

      this.pc.onicecandidate = (event) => {
        if (event.candidate) {
          reportWebRtcCandidate(this.remoteCallUser.id, this.callId, {
            callId: this.callId,
            type: "candidate",
            remoteCallUser: this.localCallUser,
            candidate: event.candidate
          })
        }
      }

      this.pc.ontrack = (event) => {

        let mediaStream = event.streams[0];
        this.$refs.remoteStream.srcObject = mediaStream;
        this.currentStream = mediaStream;
      };

      this.pc.onconnectionstatechange = () => {
        console.log(`连接状态: ${this.pc.connectionState}`);
        if (this.pc.connectionState === 'disconnected' ||
            this.pc.connectionState === 'failed' ||
            this.pc.connectionState === 'closed') {
          this.onErrorHangup();
        }
      };

      this.pc.oniceconnectionstatechange = () => {
        console.log(`ICE连接状态: ${this.pc.iceConnectionState}`);
        if (this.pc.iceConnectionState === 'disconnected' ||
            this.pc.iceConnectionState === 'failed' ||
            this.pc.iceConnectionState === 'closed') {
          this.onErrorHangup();
        }
      }

    },
    unSub(){
      unSubWebRtcOffer(this.localCallUser.id, this.callId);
      unSubWebRtcAnswer(this.localCallUser.id, this.callId);
      unSubWebRtcCandidate(this.localCallUser.id, this.callId);
      unSubWebRtcHangup(this.localCallUser.id, this.callId)
    },
    swapWindow(){
      this.swapSingleChatWindow();
      this.castFullScreen = !this.castFullScreen;
    }
  },
  watch: {
    'localStream.using' (newValue , oldValue){
       if (newValue !== oldValue) {
         this.resetPCMediaTrack();
       }
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    reportWebRtcHangup(this.remoteCallUser.id, this.callId, {
      callId: this.callId,
      type: this.callCommand.hangup,
      remoteCallUser: this.localCallUser,
    })
    this.unSub();
    this.$refs.remoteStream = null;
    this.pc.close();
    this.callId = null;
    this.remoteCallUser = null;
    this.localCallUser = null;
    this.currentStream = null;
  }
}
</script>

<style scoped>
.side-av-window-module {
  width: 100%;
  height: 100%;
  border-radius: 10px;
  overflow: hidden;
  position: absolute;
  z-index: 5;
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 0 5px rgba(255, 255, 255, 0.4);
  transition: none;
  cursor: grab;
}

video {
  width: 100%;
  height: 100%;
  object-fit: fill;
}


.video-controls {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s, visibility 0.3s;
}

.controls-visible {
  opacity: 1;
  visibility: visible;
}


.control-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: background-color 0.3s;
}

.control-btn:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

</style>